package org.dromara.web.service.plugins;


import com.alibaba.fastjson.JSONObject;
import com.wechat.pay.java.service.payments.nativepay.model.PrepayResponse;
import org.bouncycastle.pqc.crypto.newhope.NHSecretKeyProcessor;
import org.dromara.dao.business.domain.MerchantPayment;
import org.dromara.dao.business.domain.User;
import org.dromara.dao.business.enums.PaymentStatusEnums;
import org.dromara.dao.business.enums.PaymentTargetEnums;
import org.dromara.dao.business.enums.PaymentTypeEnums;
import org.dromara.dao.business.enums.UserTypeEnums;
import org.dromara.dao.business.mapper.MerchantPaymentMapper;
import org.dromara.dao.business.mapper.UserMapper;
import org.dromara.dao.business.mapper.UserTypeSettingMapper;
import org.dromara.web.plugins.alipay.AlipayService;
import org.dromara.web.plugins.weixin.WeixinPayService;
import org.dromara.web.utils.UserTypeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;

@Service
public class PaymentService {


    @Autowired
    MerchantPaymentMapper merchantPaymentMapper;

    @Autowired
    WeixinPayService weixinPayService;
    @Autowired
    AlipayService alipayService;
    @Autowired
    UserMapper userMapper;
    @Autowired
    UserTypeSettingMapper userTypeSettingMapper;



    public MerchantPayment paymentDetail(Long paymentId) {
        return merchantPaymentMapper.selectById(paymentId);
    }


    @Transactional
    public Object createOrder(Long userId, String type, String payType, BigDecimal amount, String params) {

        MerchantPayment merchantPayment = new MerchantPayment();
        merchantPayment.setUserId(userId);
        merchantPayment.setType(type);
        merchantPayment.setPaymentType(payType);
        merchantPayment.setPaymentParam(params);
        merchantPayment.setAmount(amount);
        merchantPayment.setStatus(PaymentStatusEnums.STATUS_HOLDING);
        merchantPaymentMapper.insert(merchantPayment);

        if (PaymentTypeEnums.TYPE_WX_NATIVE.equals(payType)) {
            PrepayResponse prepayResponse = weixinPayService.wechatJSAPIPay(merchantPayment.getId().toString(), amount);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("codeUrl", prepayResponse.getCodeUrl());
            jsonObject.put("paymentId", merchantPayment.getId());
            return jsonObject;
        } else if (PaymentTypeEnums.TYPE_WX_H5.equals(payType)) {

        } else if (PaymentTypeEnums.TYPE_ALIPAY_PC.equals(payType)) {
            Object ret = alipayService.alipayPcPrePay(merchantPayment.getId().toString(), amount);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("codeUrl", ret);
            jsonObject.put("paymentId", merchantPayment.getId());
            return jsonObject;
        }
        return new Object();
    }

    @Transactional
    public void paymentCallback(String tradeNo, boolean success) {
        Long id = Long.valueOf(tradeNo);
        MerchantPayment merchantPayment = merchantPaymentMapper.selectById(id);
        if (merchantPayment == null) {
            return;
        }
        if (!PaymentStatusEnums.STATUS_HOLDING.equals(merchantPayment.getStatus())) {
            return;
        }

        merchantPayment.setStatus(success ? PaymentStatusEnums.STATUS_COMPLETE: PaymentStatusEnums.STATUS_CANCEL);
        merchantPayment.setCallbackTime(LocalDateTime.now());
        merchantPaymentMapper.updateById(merchantPayment);

        if (PaymentTargetEnums.TARGET_VIP.equals(merchantPayment.getType()) && success) {
            userVipPaymentSuccess(merchantPayment.getUserId(), merchantPayment.getPaymentParam());
        }
    }


    private void userVipPaymentSuccess(Long userId, String param) {
        User user = userMapper.selectById(userId);
        JSONObject jsonObject = JSONObject.parseObject(param);
        Long settingId = jsonObject.getLong("settingId");
        String duration = jsonObject.getString("duration");
        int targetType = jsonObject.getInteger("userType");

        Integer userType = UserTypeUtils.userType(user);

        if (userType == null || userType == UserTypeEnums.USER_TYPE_COMMON) {
            LocalDateTime endTime = "0".equals(duration) ? LocalDateTime.now().plusMonths(1) : LocalDateTime.now().plusYears(1);
            user.setUserType(targetType);
            user.setUserTypeStart(LocalDateTime.now());
            user.setUserTypeEnd(endTime);
            userMapper.updateById(user);
        } else if (userType == UserTypeEnums.USER_TYPE_MOBILE) {
            LocalDateTime startTime = null;
            if (targetType == UserTypeEnums.USER_TYPE_MOBILE) {
                startTime = user.getUserTypeEnd() == null || user.getUserTypeEnd().isBefore(LocalDateTime.now()) ? LocalDateTime.now() : user.getUserTypeEnd();
            } else {
                startTime = LocalDateTime.now();
            }
            LocalDateTime endTime = "0".equals(duration) ? startTime.plusMonths(1) : startTime.plusYears(1);
            user.setUserType(targetType);
            user.setUserTypeStart(startTime);
            user.setUserTypeEnd(endTime);
            userMapper.updateById(user);
        } else if (userType == UserTypeEnums.USER_TYPE_ALL && targetType == UserTypeEnums.USER_TYPE_ALL) {
            LocalDateTime endTime = "0".equals(duration) ? user.getUserTypeEnd().plusMonths(1) : user.getUserTypeEnd().plusYears(1);
            user.setUserTypeEnd(endTime);
            userMapper.updateById(user);
        }
    }
}
